home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / Mail / RCS / quit.c,v < prev    next >
Encoding:
Text File  |  1990-12-18  |  10.1 KB  |  496 lines

  1. head     1.1;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    shirriff:1.1; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.1
  10. date     90.12.17.19.01.48;  author shirriff;  state Exp;
  11. branches ;
  12. next     ;
  13.  
  14.  
  15. desc
  16. @@
  17.  
  18.  
  19.  
  20. 1.1
  21. log
  22. @Initial revision
  23. @
  24. text
  25. @/*
  26.  * Copyright (c) 1980 Regents of the University of California.
  27.  * All rights reserved.
  28.  *
  29.  * Redistribution and use in source and binary forms are permitted
  30.  * provided that the above copyright notice and this paragraph are
  31.  * duplicated in all such forms and that any documentation,
  32.  * advertising materials, and other materials related to such
  33.  * distribution and use acknowledge that the software was developed
  34.  * by the University of California, Berkeley.  The name of the
  35.  * University may not be used to endorse or promote products derived
  36.  * from this software without specific prior written permission.
  37.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  38.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  39.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  40.  */
  41.  
  42. #ifndef lint
  43. static char sccsid[] = "@@(#)quit.c    5.11 (Berkeley) 1/16/89";
  44. #endif /* not lint */
  45.  
  46. #include "rcv.h"
  47. #include <sys/stat.h>
  48. #include <sys/file.h>
  49.  
  50. /*
  51.  * Rcv -- receive mail rationally.
  52.  *
  53.  * Termination processing.
  54.  */
  55.  
  56. /*
  57.  * The "quit" command.
  58.  */
  59. quitcmd()
  60. {
  61.     /*
  62.      * If we are sourcing, then return 1 so execute() can handle it.
  63.      * Otherwise, return -1 to abort command loop.
  64.      */
  65.     if (sourcing)
  66.         return 1;
  67.     return -1;
  68. }
  69.  
  70. /*
  71.  * Save all of the undetermined messages at the top of "mbox"
  72.  * Save all untouched messages back in the system mailbox.
  73.  * Remove the system mailbox, if none saved there.
  74.  */
  75.  
  76. quit()
  77. {
  78.     int mcount, p, modify, autohold, anystat, holdbit, nohold;
  79.     FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf;
  80.     register struct message *mp;
  81.     register int c;
  82.     extern char tempQuit[], tempResid[];
  83.     struct stat minfo;
  84.     char *mbox;
  85.  
  86.     /*
  87.      * If we are read only, we can't do anything,
  88.      * so just return quickly.
  89.      */
  90.     if (readonly)
  91.         return;
  92.     /*
  93.      * If editing (not reading system mail box), then do the work
  94.      * in edstop()
  95.      */
  96.     if (edit) {
  97.         edstop();
  98.         return;
  99.     }
  100.  
  101.     /*
  102.      * See if there any messages to save in mbox.  If no, we
  103.      * can save copying mbox to /tmp and back.
  104.      *
  105.      * Check also to see if any files need to be preserved.
  106.      * Delete all untouched messages to keep them out of mbox.
  107.      * If all the messages are to be preserved, just exit with
  108.      * a message.
  109.      */
  110.  
  111.     fbuf = fopen(mailname, "r");
  112.     if (fbuf == NULL)
  113.         goto newmail;
  114.     flock(fileno(fbuf), LOCK_EX);
  115.     rbuf = NULL;
  116.     if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) {
  117.         printf("New mail has arrived.\n");
  118.         rbuf = fopen(tempResid, "w");
  119.         if (rbuf == NULL || fbuf == NULL)
  120.             goto newmail;
  121. #ifdef APPEND
  122.         fseek(fbuf, mailsize, 0);
  123.         while ((c = getc(fbuf)) != EOF)
  124.             (void) putc(c, rbuf);
  125. #else
  126.         p = minfo.st_size - mailsize;
  127.         while (p-- > 0) {
  128.             c = getc(fbuf);
  129.             if (c == EOF)
  130.                 goto newmail;
  131.             (void) putc(c, rbuf);
  132.         }
  133. #endif
  134.         fclose(rbuf);
  135.         if ((rbuf = fopen(tempResid, "r")) == NULL)
  136.             goto newmail;
  137.         remove(tempResid);
  138.     }
  139.  
  140.     /*
  141.      * Adjust the message flags in each message.
  142.      */
  143.  
  144.     anystat = 0;
  145.     autohold = value("hold") != NOSTR;
  146.     holdbit = autohold ? MPRESERVE : MBOX;
  147.     nohold = MBOX|MSAVED|MDELETED|MPRESERVE;
  148.     if (value("keepsave") != NOSTR)
  149.         nohold &= ~MSAVED;
  150.     for (mp = &message[0]; mp < &message[msgCount]; mp++) {
  151.         if (mp->m_flag & MNEW) {
  152.             mp->m_flag &= ~MNEW;
  153.             mp->m_flag |= MSTATUS;
  154.         }
  155.         if (mp->m_flag & MSTATUS)
  156.             anystat++;
  157.         if ((mp->m_flag & MTOUCH) == 0)
  158.             mp->m_flag |= MPRESERVE;
  159.         if ((mp->m_flag & nohold) == 0)
  160.             mp->m_flag |= holdbit;
  161.     }
  162.     modify = 0;
  163.     if (Tflag != NOSTR) {
  164.         if ((readstat = fopen(Tflag, "w")) == NULL)
  165.             Tflag = NOSTR;
  166.     }
  167.     for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
  168.         if (mp->m_flag & MBOX)
  169.             c++;
  170.         if (mp->m_flag & MPRESERVE)
  171.             p++;
  172.         if (mp->m_flag & MODIFY)
  173.             modify++;
  174.         if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) {
  175.             char *id;
  176.  
  177.             if ((id = hfield("article-id", mp)) != NOSTR)
  178.                 fprintf(readstat, "%s\n", id);
  179.         }
  180.     }
  181.     if (Tflag != NOSTR)
  182.         fclose(readstat);
  183.     if (p == msgCount && !modify && !anystat) {
  184.         printf("Held %d message%s in %s\n",
  185.             p, p == 1 ? "" : "s", mailname);
  186.         fclose(fbuf);
  187.         return;
  188.     }
  189.     if (c == 0) {
  190.         if (p != 0) {
  191.             writeback(rbuf);
  192.             fclose(fbuf);
  193.             return;
  194.         }
  195.         goto cream;
  196.     }
  197.  
  198.     /*
  199.      * Create another temporary file and copy user's mbox file
  200.      * darin.  If there is no mbox, copy nothing.
  201.      * If he has specified "append" don't copy his mailbox,
  202.      * just copy saveable entries at the end.
  203.      */
  204.  
  205.     mbox = expand("&");
  206.     mcount = c;
  207.     if (value("append") == NOSTR) {
  208.         if ((obuf = fopen(tempQuit, "w")) == NULL) {
  209.             perror(tempQuit);
  210.             fclose(fbuf);
  211.             return;
  212.         }
  213.         if ((ibuf = fopen(tempQuit, "r")) == NULL) {
  214.             perror(tempQuit);
  215.             remove(tempQuit);
  216.             fclose(obuf);
  217.             fclose(fbuf);
  218.             return;
  219.         }
  220.         remove(tempQuit);
  221.         if ((abuf = fopen(mbox, "r")) != NULL) {
  222.             while ((c = getc(abuf)) != EOF)
  223.                 (void) putc(c, obuf);
  224.             fclose(abuf);
  225.         }
  226.         if (ferror(obuf)) {
  227.             perror(tempQuit);
  228.             fclose(ibuf);
  229.             fclose(obuf);
  230.             fclose(fbuf);
  231.             return;
  232.         }
  233.         fclose(obuf);
  234.         close(creat(mbox, 0600));
  235.         if ((obuf = fopen(mbox, "r+")) == NULL) {
  236.             perror(mbox);
  237.             fclose(ibuf);
  238.             fclose(fbuf);
  239.             return;
  240.         }
  241.     }
  242.     if (value("append") != NOSTR) {
  243.         if ((obuf = fopen(mbox, "a")) == NULL) {
  244.             perror(mbox);
  245.             fclose(fbuf);
  246.             return;
  247.         }
  248.         fchmod(fileno(obuf), 0600);
  249.     }
  250.     for (mp = &message[0]; mp < &message[msgCount]; mp++)
  251.         if (mp->m_flag & MBOX)
  252.             if (send(mp, obuf, saveignore, NOSTR) < 0) {
  253.                 perror(mbox);
  254.                 fclose(ibuf);
  255.                 fclose(obuf);
  256.                 fclose(fbuf);
  257.                 return;
  258.             }
  259.  
  260.     /*
  261.      * Copy the user's old mbox contents back
  262.      * to the end of the stuff we just saved.
  263.      * If we are appending, this is unnecessary.
  264.      */
  265.  
  266.     if (value("append") == NOSTR) {
  267.         rewind(ibuf);
  268.         c = getc(ibuf);
  269.         while (c != EOF) {
  270.             (void) putc(c, obuf);
  271.             if (ferror(obuf))
  272.                 break;
  273.             c = getc(ibuf);
  274.         }
  275.         fclose(ibuf);
  276.         fflush(obuf);
  277.     }
  278.     trunc(obuf);
  279.     if (ferror(obuf)) {
  280.         perror(mbox);
  281.         fclose(obuf);
  282.         fclose(fbuf);
  283.         return;
  284.     }
  285.     fclose(obuf);
  286.     if (mcount == 1)
  287.         printf("Saved 1 message in mbox\n");
  288.     else
  289.         printf("Saved %d messages in mbox\n", mcount);
  290.  
  291.     /*
  292.      * Now we are ready to copy back preserved files to
  293.      * the system mailbox, if any were requested.
  294.      */
  295.  
  296.     if (p != 0) {
  297.         writeback(rbuf);
  298.         fclose(fbuf);
  299.         return;
  300.     }
  301.  
  302.     /*
  303.      * Finally, remove his /usr/mail file.
  304.      * If new mail has arrived, copy it back.
  305.      */
  306.  
  307. cream:
  308.     if (rbuf != NULL) {
  309.         abuf = fopen(mailname, "r+");
  310.         if (abuf == NULL)
  311.             goto newmail;
  312.         while ((c = getc(rbuf)) != EOF)
  313.             (void) putc(c, abuf);
  314.         fclose(rbuf);
  315.         trunc(abuf);
  316.         fclose(abuf);
  317.         alter(mailname);
  318.         fclose(fbuf);
  319.         return;
  320.     }
  321.     demail();
  322.     fclose(fbuf);
  323.     return;
  324.  
  325. newmail:
  326.     printf("Thou hast new mail.\n");
  327.     if (fbuf != NULL)
  328.         fclose(fbuf);
  329. }
  330.  
  331. /*
  332.  * Preserve all the appropriate messages back in the system
  333.  * mailbox, and print a nice message indicated how many were
  334.  * saved.  On any error, just return -1.  Else return 0.
  335.  * Incorporate the any new mail that we found.
  336.  */
  337. writeback(res)
  338.     register FILE *res;
  339. {
  340.     register struct message *mp;
  341.     register int p, c;
  342.     FILE *obuf;
  343.  
  344.     p = 0;
  345.     if ((obuf = fopen(mailname, "r+")) == NULL) {
  346.         perror(mailname);
  347.         return(-1);
  348.     }
  349. #ifndef APPEND
  350.     if (res != NULL)
  351.         while ((c = getc(res)) != EOF)
  352.             (void) putc(c, obuf);
  353. #endif
  354.     for (mp = &message[0]; mp < &message[msgCount]; mp++)
  355.         if ((mp->m_flag&MPRESERVE)||(mp->m_flag&MTOUCH)==0) {
  356.             p++;
  357.             if (send(mp, obuf, (struct ignoretab *)0, NOSTR) < 0) {
  358.                 perror(mailname);
  359.                 fclose(obuf);
  360.                 return(-1);
  361.             }
  362.         }
  363. #ifdef APPEND
  364.     if (res != NULL)
  365.         while ((c = getc(res)) != EOF)
  366.             (void) putc(c, obuf);
  367. #endif
  368.     fflush(obuf);
  369.     trunc(obuf);
  370.     if (ferror(obuf)) {
  371.         perror(mailname);
  372.         fclose(obuf);
  373.         return(-1);
  374.     }
  375.     if (res != NULL)
  376.         fclose(res);
  377.     fclose(obuf);
  378.     alter(mailname);
  379.     if (p == 1)
  380.         printf("Held 1 message in %s\n", mailname);
  381.     else
  382.         printf("Held %d messages in %s\n", p, mailname);
  383.     return(0);
  384. }
  385.  
  386. /*
  387.  * Terminate an editing session by attempting to write out the user's
  388.  * file from the temporary.  Save any new stuff appended to the file.
  389.  */
  390. edstop()
  391. {
  392.     register int gotcha, c;
  393.     register struct message *mp;
  394.     FILE *obuf, *ibuf, *readstat;
  395.     struct stat statb;
  396.     char tempname[30];
  397.     char *mktemp();
  398.  
  399.     if (readonly)
  400.         return;
  401.     holdsigs();
  402.     if (Tflag != NOSTR) {
  403.         if ((readstat = fopen(Tflag, "w")) == NULL)
  404.             Tflag = NOSTR;
  405.     }
  406.     for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) {
  407.         if (mp->m_flag & MNEW) {
  408.             mp->m_flag &= ~MNEW;
  409.             mp->m_flag |= MSTATUS;
  410.         }
  411.         if (mp->m_flag & (MODIFY|MDELETED|MSTATUS))
  412.             gotcha++;
  413.         if (Tflag != NOSTR && (mp->m_flag & (MREAD|MDELETED)) != 0) {
  414.             char *id;
  415.  
  416.             if ((id = hfield("article-id", mp)) != NOSTR)
  417.                 fprintf(readstat, "%s\n", id);
  418.         }
  419.     }
  420.     if (Tflag != NOSTR)
  421.         fclose(readstat);
  422.     if (!gotcha || Tflag != NOSTR)
  423.         goto done;
  424.     ibuf = NULL;
  425.     if (stat(mailname, &statb) >= 0 && statb.st_size > mailsize) {
  426.         strcpy(tempname, "/tmp/mboxXXXXXX");
  427.         mktemp(tempname);
  428.         if ((obuf = fopen(tempname, "w")) == NULL) {
  429.             perror(tempname);
  430.             relsesigs();
  431.             reset(0);
  432.         }
  433.         if ((ibuf = fopen(mailname, "r")) == NULL) {
  434.             perror(mailname);
  435.             fclose(obuf);
  436.             remove(tempname);
  437.             relsesigs();
  438.             reset(0);
  439.         }
  440.         fseek(ibuf, mailsize, 0);
  441.         while ((c = getc(ibuf)) != EOF)
  442.             (void) putc(c, obuf);
  443.         fclose(ibuf);
  444.         fclose(obuf);
  445.         if ((ibuf = fopen(tempname, "r")) == NULL) {
  446.             perror(tempname);
  447.             remove(tempname);
  448.             relsesigs();
  449.             reset(0);
  450.         }
  451.         remove(tempname);
  452.     }
  453.     printf("\"%s\" ", mailname);
  454.     fflush(stdout);
  455.     if ((obuf = fopen(mailname, "r+")) == NULL) {
  456.         perror(mailname);
  457.         relsesigs();
  458.         reset(0);
  459.     }
  460.     trunc(obuf);
  461.     c = 0;
  462.     for (mp = &message[0]; mp < &message[msgCount]; mp++) {
  463.         if ((mp->m_flag & MDELETED) != 0)
  464.             continue;
  465.         c++;
  466.         if (send(mp, obuf, (struct ignoretab *) NULL, NOSTR) < 0) {
  467.             perror(mailname);
  468.             relsesigs();
  469.             reset(0);
  470.         }
  471.     }
  472.     gotcha = (c == 0 && ibuf == NULL);
  473.     if (ibuf != NULL) {
  474.         while ((c = getc(ibuf)) != EOF)
  475.             (void) putc(c, obuf);
  476.         fclose(ibuf);
  477.     }
  478.     fflush(obuf);
  479.     if (ferror(obuf)) {
  480.         perror(mailname);
  481.         relsesigs();
  482.         reset(0);
  483.     }
  484.     fclose(obuf);
  485.     if (gotcha) {
  486.         remove(mailname);
  487.         printf("removed\n");
  488.     } else
  489.         printf("complete\n");
  490.     fflush(stdout);
  491.  
  492. done:
  493.     relsesigs();
  494. }
  495. @
  496.